package com.gillion.grule.client.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.apache.commons.lang3.time.DateUtils;
import org.mvel2.MVEL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;




public class RuleDateUtils
        extends DateUtils
{
    private static final Logger logger = LoggerFactory.getLogger(RuleDateUtils.class);







    public static long interval(Date source, Date target) {
        return source.getTime() - target.getTime();
    }







    public static int intervalYears(Date source, Date target) {
        return source.getYear() - target.getYear();
    }







    public static int intervalMonths(Date source, Date target) {
        return (source.getYear() - target.getYear()) * 12 + source.getMonth() - target.getMonth();
    }







    public static int intervalDays(Date source, Date target) {
        return intervalHours(source, target) / 60;
    }







    public static int intervalHours(Date source, Date target) {
        return intervalMinutes(source, target) / 60;
    }







    public static int intervalMinutes(Date source, Date target) {
        return intervalSeconds(source, target) / 60;
    }







    public static int intervalSeconds(Date source, Date target) {
        return (int)(interval(source, target) / 1000L);
    }








    public static Date date(String date, String pattern) throws ParseException {
        return DateUtils.parseDate(date, new String[] { pattern });
    }







    public static Date date(String date) throws ParseException {
        return DateUtils.parseDate(date, new String[] { "yyyy-MM-dd HH:mm:SS" });
    }






    public static Date lastDayTime(Date source) {
        Date date = (Date)source.clone();
        date.setHours(23);
        date.setMinutes(59);
        date.setSeconds(59);
        return date;
    }





    public static Date lastDayTime(Object source) {
        Date date = null;
        if (source instanceof String) {
            try {
                date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse((String)source);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            date = (Date)source;
        }
        date.setHours(23);
        date.setMinutes(59);
        date.setSeconds(59);
        return date;
    }






    public static Date lastDayTime(String source) {
        Date dateStr = null;
        try {
            dateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(source);
        } catch (Exception e) {
            e.printStackTrace();
        }
        dateStr.setHours(23);
        dateStr.setMinutes(59);
        dateStr.setSeconds(59);
        MVEL.eval("this!='2017-01-01 23:59:59'", dateStr);
        return dateStr;
    }






    public static Date newDayTime(Date source) {
        Date date = (Date)source.clone();
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        return date;
    }








    public static Date addHours(Object source, double amount) {
        int hour = (int)amount;
        int min = (int)((amount - hour) * 60.0D);

        if (source == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Date date = null;
        if (source instanceof Date) {
            date = addHours((Date)source, hour);
            date = addMinutes(date, min);
            return date;
        }

        if (source instanceof String) {
            try {
                Date dateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse((String)source);
                date = addHours(dateStr, hour);
                date = addMinutes(date, min);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return date;
        }
        return null;
    }

    public static Date addHours(Object source, String amount) {
        double hour = Double.parseDouble(amount);
        return addHours(source, hour);
    }

    public static Date addHours(Object source, Object amount) {
        double hour = Double.parseDouble(amount.toString());
        return addHours(source, hour);
    }







    public static Long compareHours(Date source1, Date source2) {
        Long hours = Long.valueOf(0L);
        try {
            long diff = source1.getTime() - source2.getTime();
            hours = Long.valueOf(diff / 3600000L);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return hours;
    }







    public static Date addHours(Date source, Object amount) {
        int hours = 0;
        if (amount instanceof String) {
            hours = Integer.parseInt((String)amount);
        }
        if (source == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar c = Calendar.getInstance();
        c.setTime(source);
        c.add(11, hours);
        return c.getTime();
    }





    public static Date nowDate() {
        Calendar c = Calendar.getInstance();
        return c.getTime();
    }




    public static int compareHour(Date source, int hour) {
        return source.getHours() - hour;
    }

    public static int compareHour(Object source, int hour) {
        Date date = new Date();
        if (source instanceof String) {
            try {
                date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse((String)source);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            date = (Date)source;
        }
        return date.getHours() - hour;
    }

    public static int compareHour(Object source, Object hour) {
        return compareHour(source, Integer.parseInt(hour.toString()));
    }

    public static int compareHour(String source, Object hour) {
        Date date = new Date();
        try {
            date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(source);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return date.getHours() - Integer.parseInt(hour.toString());
    }







    public static Date replaceDate(Date date, String hourMinSec) {
        String[] time = hourMinSec.split(":");
        date.setHours(Integer.parseInt(time[0]));
        date.setMinutes(Integer.parseInt(time[1]));
        date.setSeconds(Integer.parseInt(time[2]));
        return date;
    }

    public static Date replaceDate(Object source, String hourMinSec) {
        Date date = new Date();
        if (source instanceof String) {
            try {
                date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse((String)source);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            date = (Date)source;
        }
        String[] time = hourMinSec.split(":");
        date.setHours(Integer.parseInt(time[0]));
        date.setMinutes(Integer.parseInt(time[1]));
        date.setSeconds(Integer.parseInt(time[2]));
        return date;
    }

    public static Date replaceDate(Object source, Object hourMinSec) {
        Date date = new Date();
        if (source instanceof String) {
            try {
                date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse((String)source);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            date = (Date)source;
        }
        String[] time = hourMinSec.toString().split(":");
        date.setHours(Integer.parseInt(time[0]));
        date.setMinutes(Integer.parseInt(time[1]));
        date.setSeconds(Integer.parseInt(time[2]));
        return date;
    }

    public static String countHours(String mes, String modifyHours) {
        String[] hourAndMin = mes.split(":");
        return (Integer.parseInt(hourAndMin[0]) - Integer.parseInt(modifyHours)) + ":" + hourAndMin[1];
    }
    public static String countHours(Object mes, String modifyHours) {
        String[] hourAndMin = mes.toString().split(":");
        return (Integer.parseInt(hourAndMin[0]) - Integer.parseInt(modifyHours)) + ":" + hourAndMin[1];
    }



    public static Object dateFormat(Date date) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String newDate = df.format(date);
        try {
            return df.parse(newDate);
        } catch (Exception e) {
            e.printStackTrace();

            return null;
        }
    }
    public static Object dateFormat(Object date) {
        if (date == null) {
            return null;
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Date nDate = new Date();
            if (date instanceof String) {
                if ("".equals(date)) {
                    return null;
                }
                nDate = df.parse(date.toString());
            } else if (date instanceof Long) {
                nDate = new Date(((Long)date).longValue());
            } else {
                nDate = (Date)date;
            }
            String newDate = df.format(nDate);
            return df.parse(newDate);
        } catch (Exception e) {
            e.printStackTrace();

            return null;
        }
    }
    public static Object dateToString(Object date) {
        Date nDate = null;
        if (date instanceof Long) {
            nDate = new Date(((Long)date).longValue());
        } else if (date instanceof Date) {
            nDate = (Date)date;
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String newDate = df.format(nDate);
        return newDate;
    }

    public static String dateToWeekDay(Object date) {
        SimpleDateFormat dateFm = new SimpleDateFormat("EEEE");
        return dateFm.format(date);
    }


    public static Object middleDate(Date date1, Date date2) {
        Long time = Long.valueOf((date1.getTime() + date2.getTime()) / 2L);
        Date date = new Date(time.longValue());
        return date;
    }
    public static Object middleDate(Object date1, Object date2) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Date fDate, sDate;
            if (date1 instanceof String) {
                fDate = df.parse(date1.toString());
            } else if (date1 instanceof Long) {
                fDate = new Date(((Long)date1).longValue());
            } else {
                fDate = (Date)date1;
            }
            if (date2 instanceof String) {
                sDate = df.parse(date2.toString());
            } else if (date2 instanceof Long) {
                sDate = new Date(((Long)date2).longValue());
            } else {
                sDate = (Date)date2;
            }
            Long time = Long.valueOf((fDate.getTime() + sDate.getTime()) / 2L);
            Date date = new Date(time.longValue());
            return date;
        } catch (Exception e) {
            logger.error("时间转换出错", e);

            return null;
        }
    }
    public static Object monthDays(Object objDate) {
        Date date = null;
        if (objDate instanceof String) {
            try {
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                date = df.parse(objDate.toString());
            } catch (Exception e) {
                logger.error("时间转换出错", e);
            }
        } else if (objDate instanceof Long) {
            date = new Date(((Long)objDate).longValue());
        } else if (objDate instanceof Date) {
            date = (Date)objDate;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return Integer.valueOf(calendar.getActualMaximum(5));
    }
    public static Object lastDayOfMonth(Object objDate) {
        Date date = null;
        if (objDate instanceof String) {
            try {
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                date = df.parse(objDate.toString());
            } catch (Exception e) {
                logger.error("时间转换出错", e);
            }
        } else if (objDate instanceof Long) {
            date = new Date(((Long)objDate).longValue());
        } else if (objDate instanceof Date) {
            date = (Date)objDate;
        }

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        calendar.set(5, calendar.getActualMaximum(5));
        calendar.set(11, 23);
        calendar.set(12, 59);
        calendar.set(13, 59);
        return calendar.getTime();
    }

    public static Integer getMonth(Object obj) {
        Date date = null;
        if (obj instanceof String) {
            try {
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                date = df.parse(obj.toString());
            } catch (Exception e) {
                logger.error("时间转换出错", e);
            }
        } else if (obj instanceof Long) {
            date = new Date(((Long)obj).longValue());
        } else if (obj instanceof Date) {
            date = (Date)obj;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return Integer.valueOf(calendar.get(2) + 1);
    }
}